Node.js 심화
작성일 : 2024.12.06
1. Node.js 내부 구조
A. V8 엔진
- Google이 개발한 고성능 JavaScript 엔진
- JavaScript 코드를 기계어로 컴파일하여 실행
- JIT(Just-In-Time) 컴파일러를 사용해 실행 시점에 최적화
B. 이벤트 루프 상세 동작
// 이벤트 루프의 실행 순서 예시
console.log('1'); // 동기 작업
setTimeout(() => {
console.log('2'); // 매크로태스크
}, 0);
Promise.resolve()
.then(() => console.log('3')); // 마이크로태스크
console.log('4');
// 출력 순서: 1, 4, 3, 2
실행 순서 설명:
- 콜 스택의 동기 작업 실행
- 마이크로태스크 큐의 작업 실행 (Promise)
- 매크로태스크 큐의 작업 실행 (setTimeout, setInterval 등)
C. libuv
- Node.js의 비동기 I/O를 처리하는 핵심 라이브러리
- 이벤트 루프 구현
- 스레드 풀을 통한 파일 시스템 작업 처리
2. 고급 개념과 기능
A. 스트림(Streams)
const fs = require('fs');
// 읽기 스트림 생성
const readStream = fs.createReadStream('input.txt');
// 쓰기 스트림 생성
const writeStream = fs.createWriteStream('output.txt');
// 파이프로 스트림 연결
readStream.pipe(writeStream);
// 스트림 이벤트 처리
readStream.on('data', (chunk) => {
console.log('데이터 청크:', chunk);
});
readStream.on('end', () => {
console.log('읽기 완료');
});
B. 버퍼(Buffer)
// 버퍼 생성
const buf = Buffer.from('Hello World');
// 버퍼 조작
console.log(buf.toString()); // Hello World
console.log(buf.length); // 11
console.log(buf[0]); // 72 (ASCII 코드)
// 버퍼 결합
const buf1 = Buffer.from('Hello ');
const buf2 = Buffer.from('World');
const buf3 = Buffer.concat([buf1, buf2]);
C. 클러스터(Cluster)
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// 마스터 프로세스
console.log(`마스터 프로세스 ${process.pid} 실행`);
// CPU 코어 수만큼 워커 생성
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`워커 ${worker.process.pid} 종료`);
});
} else {
// 워커 프로세스
http.createServer((req, res) => {
res.writeHead(200);
res.end('hello world\n');
}).listen(8000);
console.log(`워커 ${process.pid} 시작`);
}
3. 디자인 패턴과 Best Practices
A. 미들웨어 패턴 (Express.js 예시)
const express = require('express');
const app = express();
// 커스텀 미들웨어
const logger = (req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
};
// 미들웨어 등록
app.use(logger);
app.use(express.json());
// 라우트 핸들러
app.get('/', (req, res) => {
res.send('Hello World');
});
app.listen(3000);
B. 에러 처리
// 비동기 에러 처리
process.on('uncaughtException', (err) => {
console.error('예상치 못한 에러:', err);
// 정상적인 종료 처리
process.exit(1);
});
// Express.js 에러 처리 미들웨어
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});